/**
 * 
 */
package com.geezdata.cps.base.shiro;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.HostFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.geezdata.cps.base.constant.ShiroConstants;
import com.google.common.base.Splitter;

/**
 * @author sszheng
 * @date 创建时间：2017年8月29日 下午5:08:42
 *
 */
public class DefaultHostFilter extends HostFilter{
	private static final Logger logger = LoggerFactory.getLogger(DefaultHostFilter.class);
	
	private List<String> authorizedIps = new ArrayList<String>();
	
	public DefaultHostFilter(String hosts) {
		authorizedIps = Splitter.on(",").splitToList(hosts);
	}
	
	private boolean isInner(String ip) {
	    String reg = "(10|172|192)\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})";//正则表达式=。 =、懒得做文字处理了、
	    Pattern p = Pattern.compile(reg);
	    Matcher matcher = p.matcher(ip);
	    return matcher.find();
	}
	
	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		if( StringUtils.isNotEmpty(httpServletRequest.getHeader(ShiroConstants.USER_SCHEDULE))) {
			if(SecurityUtils.getSubject().isAuthenticated()) {
				if(ShiroConstants.USER_SCHEDULE.equals(SecurityUtils.getSubject().getPrincipal())) {
					return true;
				} else {
					logger.error("HEADER包含SCHEDULE,但是当前用户不是SCHEDULE.当前用户：" + SecurityUtils.getSubject().getPrincipal());
				}
				
			}
			
			String host = getIpAddr(httpServletRequest);
			if(isInner(host)) {
				logger.info("current ip address: " + host);
			}
			if(authorizedIps.contains(host)) {
				logger.info("address: " + host + " has authorized");
				Subject currentUser = SecurityUtils.getSubject(); 
				currentUser.logout();
				UsernamePasswordToken token = new UsernamePasswordToken(ShiroConstants.USER_SCHEDULE, ShiroConstants.USER_SCHEDULE);
				currentUser.login(token);
				if(currentUser.isAuthenticated()) {
					logger.info("currentUser authenticated by shiro-robot; session Id" + currentUser.getSession().getId() + "; currentUser " + currentUser.getPrincipal()); 
				}
			}
		} 
		return true;
	}
	
	private String getIpAddr(HttpServletRequest request) {  
	    String ip = request.getHeader("x-forwarded-for");//先从nginx自定义配置获取  
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("X-real-ip");  
	    }  
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("Proxy-Client-IP");  
	    }  
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("WL-Proxy-Client-IP");  
	    }  
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getRemoteAddr();  
	    }  
	    return ip;  
	}
	
}
